﻿using System;

namespace TAS.XtOM
{
	[AttributeUsage(AttributeTargets.Property, AllowMultiple=false)]
	public class MapperInstructionsAttribute : Attribute
	{
		private Type nodeListType;
		private Type convertTo;
		private string xpath;
		private INodeValueSelector valueSelector;
		private NodeValueSelection selection;

		public MapperInstructionsAttribute(string xpath)
		{
			if (string.IsNullOrEmpty(xpath))
				throw new ArgumentNullException("xpath");
			this.xpath = xpath;

			selection = NodeValueSelection.InnerText;

			CreateNodeValueSelector();
		}

		public MapperInstructionsAttribute(string xpath, NodeValueSelection selection)
		{
			if (string.IsNullOrEmpty(xpath))
				throw new ArgumentNullException("xpath");
			this.xpath = xpath;

			this.selection = selection;

			CreateNodeValueSelector();
		}

		public MapperInstructionsAttribute()
		{
			// TODO: Complete member initialization
		}

		public virtual void CreateNodeValueSelector()
		{
			valueSelector = new StandardNodeValueSelector(selection);
		}

		public bool TypeConvertionEnabled { get; set; }
		public Type ConvertTo 
		{
			get
			{
				return convertTo;
			}
			set
			{
				if (value.GetInterface(typeof(IConvertible).FullName) == null)
					throw new ArgumentException(string.Format("Type of {0} must implement interface IConvertible or derived class to be able to be converted.", value.ToString()), "ConvertTo");
				convertTo = value;
			}
		}
		public string XPath 
		{
			get
			{
				return xpath;
			}
		}
		public NodeType NodeType { get; set; }
		public Type NodeListType
		{
			get
			{
				return nodeListType;
			}
			set
			{
				if (value == null)
					throw new ArgumentNullException("NodeListType");
				if (value.GetInterface(typeof(IXmlMappedObject).FullName) == null)
					throw new ArgumentException(string.Format("Type of {0} must implement interface IXmlParsedObject or derived class.", value.ToString()), "NodeListType");
				nodeListType = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <remarks>Default <see cref="INodeValueSelector"/> is <see cref="StandardNodeValueSelector"/></remarks>
		public INodeValueSelector ValueSelector 
		{
			get
			{
				return valueSelector;
			}
			set
			{
				valueSelector = value;
			}
		}
	}

	public enum NodeType
	{
		SingleNode,
		NodeList
	}
}
